import json
from dataclasses import dataclass
from typing import List, Dict, Any
from utils.logger import get_logger

# Create logger instance
logger = get_logger("config_loader.py+load_configs")


@dataclass
class BrokerConfig:
    host: str
    port: int
    protocol: str
    username: str
    password: str
    client_id: str
    cycle_delay: int
    retry_delay: int
    keepalive: int
    timeout: int
    tls_enabled: bool


@dataclass
class PublishingConfig:
    topic_prefix: str
    qos: int
    retain: bool
    publish_interval: int


@dataclass
class MqttConfig:
    broker: BrokerConfig
    publishing: PublishingConfig


@dataclass
class PlcConnectionConfig:
    protocol: str
    server_ip: str
    server_port: int
    slave_id: int
    timeout: int
    poll_interval: int
    cycle_delay: int
    retry_delay: int
    retry_count: int


@dataclass
class PlcRegister:
    type: str
    addr: List[int]
    name_cn: str
    name_en: str
    len: int
    reg: str
    comment: str


@dataclass
class PlcParameter:
    name_cn: str
    name_en: str
    type: str
    addr: List[int]
    len: int
    reg: str
    default: int
    min: int
    max: int
    unit: str
    comment: str


@dataclass
class PlcConfig:
    connection: PlcConnectionConfig
    equip: str
    plc_model: str
    id: str
    name: str
    registers: List[PlcRegister]
    parameters: List[PlcParameter] = None


def load_mqtt_config(file_path: str = "config/mqtt_config.json") -> MqttConfig:
    """Load MQTT configuration"""
    with open(file_path, 'r', encoding='utf-8') as f:
        data = json.load(f)
    
    broker_data = data['broker']
    publishing_data = data['publishing']
    
    return MqttConfig(
        broker=BrokerConfig(
            host=broker_data['host'],
            port=broker_data['port'],
            protocol=broker_data['protocol'],
            username=broker_data['username'],
            password=broker_data['password'],
            client_id=broker_data['client_id'],
            cycle_delay=broker_data['cycle_delay'],
            retry_delay=broker_data['retry_delay'],
            keepalive=broker_data['keepalive'],
            timeout=broker_data['timeout'],
            tls_enabled=broker_data['tls_enabled']
        ),
        publishing=PublishingConfig(
            topic_prefix=publishing_data['topic_prefix'],
            qos=publishing_data['qos'],
            retain=publishing_data['retain'],
            publish_interval=publishing_data['publish_interval']
        )
    )


def load_plc_config(file_path: str = "config/plc_config.json") -> PlcConfig:
    """Load PLC configuration"""
    with open(file_path, 'r', encoding='utf-8') as f:
        data = json.load(f)
    
    connection_data = data['connection']
    
    # Fix the field name mismatch - it's 'list' in JSON but should be 'registers'
    registers_data = data.get('list', [])
    parameters_data = data.get('parameters', [])
    
    connection = PlcConnectionConfig(
        protocol=connection_data['protocol'],
        server_ip=connection_data['server_ip'],
        server_port=connection_data['server_port'],
        slave_id=connection_data['slave_id'],
        timeout=connection_data['timeout'],
        poll_interval=connection_data['poll_interval'],
        cycle_delay=connection_data['cycle_delay'],
        retry_delay=connection_data['retry_delay'],
        retry_count=connection_data['retry_count']
    )
    
    registers = []
    for reg_data in registers_data:
        register = PlcRegister(
            type=reg_data['type'],
            addr=reg_data['addr'],
            name_cn=reg_data['name_cn'],
            name_en=reg_data['name_en'],
            len=int(reg_data['len']) if isinstance(reg_data['len'], str) and reg_data['len'].isdigit() else reg_data['len'],
            reg=reg_data['reg'],
            comment=reg_data['comment']
        )
        registers.append(register)
        
    parameters = []
    for param_data in parameters_data:
        parameter = PlcParameter(
            name_cn=param_data['name_cn'],
            name_en=param_data['name_en'],
            type=param_data['type'],
            addr=param_data['addr'],
            len=param_data['len'],
            reg=param_data['reg'],
            default=param_data['default'],
            min=param_data['min'],
            max=param_data['max'],
            unit=param_data['unit'],
            comment=param_data['comment']
        )
        parameters.append(parameter)
    
    # Fix potential whitespace in id field
    device_id = data.get('id', '').strip()
    
    return PlcConfig(
        connection=connection,
        equip=data.get('equip', ''),
        plc_model=data.get('plc_model', ''),
        id=device_id,
        name=data.get('Name', ''),  # Note: JSON uses 'Name' not 'name'
        registers=registers,
        parameters=parameters
    )
